package com.qingshu.common.util.sftp;


import com.jcraft.jsch.*;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.*;

/**
 * 文件传输工具
 */
public class FTPUtil {
    private static final Logger log = LoggerFactory.getLogger(FTPUtil.class);
    public ChannelSftp sftp;
    private Session session;
    private String username;
    private String password;
    private String privateKey;
    private String host;
    private int port;

    public FTPUtil(String username, String password, String host, int port) {
        this.username = username;
        this.password = password;
        this.host = host;
        this.port = port;
    }

    public FTPUtil(String username, String host, int port, String privateKey) {
        this.username = username;
        this.host = host;
        this.port = port;
        this.privateKey = privateKey;
    }

    public FTPUtil() {
    }

    public void login() {
        try {
            JSch e = new JSch();
            if (this.privateKey != null) {
                e.addIdentity(this.privateKey);
            }

            this.session = e.getSession(this.username, this.host, this.port);
            if (this.password != null) {
                this.session.setPassword(this.password);
            }

            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            this.session.setConfig(config);
            this.session.connect();
            Channel channel = this.session.openChannel("sftp");
            channel.connect();
            this.sftp = (ChannelSftp) channel;
        } catch (JSchException var4) {
            log.error("HeaderUtil2.login:连接sftp服务器异常", var4);
        }

    }

    public void logout() {
        if (this.sftp != null && this.sftp.isConnected()) {
            this.sftp.disconnect();
        }

        if (this.session != null && this.session.isConnected()) {
            this.session.disconnect();
        }

    }

    public void upload(String basePath, String sftpFileName, InputStream input) throws SftpException {
        this.createDir(basePath, this.sftp);
        this.sftp.cd(basePath);
        this.sftp.put(input, sftpFileName);
    }
    /**
     * 下载文件
     *
     * @param downloadFilePath 下载的文件完整目录
     * @param saveFile     存在本地的路径
     */
    public File download(String downloadFilePath, String saveFile) {
        FileOutputStream fileOutputStream =null;
        try {
            int i = downloadFilePath.lastIndexOf('/');
            if (i == -1){
                return null;
            }
            sftp.cd(downloadFilePath.substring(0, i));
            File file = new File(saveFile);
            fileOutputStream = new FileOutputStream(file);
            sftp.get(downloadFilePath.substring(i + 1), fileOutputStream);
            fileOutputStream.close();
            return file;
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        }finally {
            if(null!=fileOutputStream){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                   log.info("关闭资源失败");
                }
            }
        }
    }
    /**
     * 上传文件
     *
     * @param directory  上传的目录
     * @param uploadFile 要上传的文件
     */
    public boolean upload(String directory, String uploadFile) {
        FileInputStream fileInputStream =null;
        try {
            sftp.cd(directory);
            File file = new File(uploadFile);
             fileInputStream = new FileInputStream(file);
            sftp.put(fileInputStream, file.getName());
            fileInputStream.close();
            return true;
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }finally {
            if(null!=fileInputStream){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }


    public void delete(String directory, String deleteFile) throws SftpException {
        this.sftp.cd(directory);
        this.sftp.rm(deleteFile);
    }

    public byte[] download(String filePath) throws SftpException, IOException {
        InputStream is = this.sftp.get(filePath);
        byte[] fileData = null;

        try {
            fileData = IOUtils.toByteArray(is);
        } catch (IOException var8) {
            log.error("下载错误", var8);
        } finally {
            is.close();
        }

        return fileData;
    }

    /*
     * 创建一个文件目录
     */
    public void createDir(String createpath, ChannelSftp sftp) {
        try {
            if (isDirExist(createpath)) {
                this.sftp.cd(createpath);
                return;
            }
            String pathArry[] = createpath.split("/");
            StringBuffer filePath = new StringBuffer("/");
            for (String path : pathArry) {
                if (path.equals("")) {
                    continue;
                }
                filePath.append(path + "/");
                if (isDirExist(filePath.toString())) {
                    sftp.cd(filePath.toString());
                } else {
                    // 建立目录
                    sftp.mkdir(filePath.toString());
                    // 进入并设置为当前目录
                    sftp.cd(filePath.toString());
                }
            }
            this.sftp.cd(createpath);
        } catch (SftpException e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断目录是否存在
     */
    public boolean isDirExist(String directory) {
        boolean isDirExistFlag = false;
        try {
            SftpATTRS sftpATTRS = sftp.lstat(directory);
            isDirExistFlag = true;
            return sftpATTRS.isDir();
        } catch (Exception e) {
            if (e.getMessage().toLowerCase().equals("no such file")) {
                isDirExistFlag = false;
            }
        }
        return isDirExistFlag;
    }



    public List<String> listFiles(String directory,boolean sign) throws SftpException {
        Vector vector = sftp.ls(directory);
        Iterator iterator = vector.iterator();
        List<String> fileList = new ArrayList<>();
        while (iterator.hasNext()) {
            ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) iterator.next();
            //文件名称
            String fileName = file.getFilename();
            if(file.getAttrs().isDir()){
                if(!fileName.equals(".") && !fileName.equals("..")){
                    if(sign){
                        String path = directory+"/"+fileName;
                        List<String> files = listFiles(path, sign);
                        fileList.addAll(files);
                    }
                }
            }else{
                fileList.add(fileName);
            }
        }
        return fileList;
    }

    public long getFileSize(String srcSftpFilePath) {
        long fileSize;//文件大于等于0则存在
        try {
            SftpATTRS sftpATTRS = sftp.lstat(srcSftpFilePath);
            fileSize = sftpATTRS.getSize();
        } catch (Exception e) {
            fileSize = -1;//获取文件大小异常
            if (e.getMessage().toLowerCase().equals("no such file")) {
                fileSize = -2;//文件不存在
            }
        }
        return fileSize;
    }
}
